<?php
/**
 * User: b179a9
 * Date: 04.09.11
 * Time: 15:59
 */

namespace G4T\Payment;

class PayPal extends \Zend_Http_Client
{

    /**
     * New class variable needed by the ecSetExpressCheckout API call.
     *
     * The live URL is: https://www.paypal.com/webscr
     * The test URL is: https://www.sandbox.paypal.com/webscr
     *
     * Let's use the test URL for now
     *
     * @var string The express checkout page URL
     */
    public $api_expresscheckout_uri;

    private $_api_version;
    private $_api_username; // These differ depending if you're in live mode or test mode.
    private $_api_password; // I'm certain you can come up with something to take that into account. :-)
    private $_api_signature = 'AQU0e5vuZCvSg-XJploSa.sGUDlpAy4pYzmc.ptw-XleUpR7TjKDANZs';

    /**
     * @var \G4T\Payment\ExpressStrategy
     */
    private $_expressStrategy;

    function __construct($uri, $options = null)
    {
        parent::__construct($uri, $options);

        $paypalParams = \Zend_Registry::get('config')->paypal;
        $this->api_expresscheckout_uri = $paypalParams->expresscheckout->uri;
        $this->_api_version = $paypalParams->api->version;
        $this->_api_username = $paypalParams->api->username;
        $this->_api_password = $paypalParams->api->password;
        $this->_api_signature = $paypalParams->api->signature;

        $this->setParameterGet('USER', urlencode($this->_api_username));
        $this->setParameterGet('PWD', urlencode($this->_api_password));
        $this->setParameterGet('SIGNATURE', urlencode($this->_api_signature));
        $this->setParameterGet('VERSION', urlencode($this->_api_version));
        $this->_expressStrategy = new NoneExpressStrategy();
    }



    /**
     * Calls the 'DoDirectPayment' API call. Note - Keep track of the
     * transaction ID on success! You'll need it to get transaction details
     * at a later date.
     *
     * @param float $amount
     * @param string $credit_card_type
     * @param string $credit_card_number
     * @param string $expiration_month
     * @param string $expiration_year
     * @param string $cvv2
     * @param string $first_name
     * @param string $last_name
     * @param string $address1
     * @param string $address2
     * @param string $city
     * @param string $state
     * @param string $zip
     * @param string $country
     * @param string $currency_code
     * @param string $ip_address
     * @param string $payment_action Can be 'Authorization' (default) or 'Sale'
     *
     * @return \Zend_Http_Response
     * @throws \Zend_Http_Client_Exception
     */
    function doDirectPayment(
        $amount,
        array $params,
        $ip_address,
        $currency_code = 'USD',
        $payment_action = 'Sale'
    )
    {
        $this->setParameterGet('METHOD', 'DoDirectPayment');

        $expiration_date = str_pad($params['month'], 2, STR_PAD_LEFT) .
            $params['year'];

        $this->setParameterGet('PAYMENTACTION', urlencode($payment_action)); // Can be 'Authorization', or 'Sale'
        $this->setParameterGet('AMT', urlencode($amount));
        $this->setParameterGet('CREDITCARDTYPE', urlencode($params['type']));
        $this->setParameterGet('ACCT', urlencode($params['number']));
        $this->setParameterGet('EXPDATE', urlencode($expiration_date));
        //        $this->setParameterGet('CVV2', urlencode($cvv2));
        $this->setParameterGet('FIRSTNAME', urlencode($params['firstname']));
        $this->setParameterGet('LASTNAME', urlencode($params['lastname']));
        $this->setParameterGet('STREET', urlencode($params['address1']));

        if (array_key_exists('address2', $params)) {
            $this->setParameterGet('STREET2', urlencode($params['address2']));
        }

        $this->setParameterGet('CITY', urlencode($params['city']));
        $this->setParameterGet('STATE', urlencode($params['state']));
        $this->setParameterGet('ZIP', urlencode($params['zip']));
        $this->setParameterGet('COUNTRYCODE', urlencode($params['country']));
        $this->setParameterGet('CURRENCYCODE', urlencode($currency_code));
        $this->setParameterGet('IPADDRESS', urlencode($ip_address));

        return $this->request(\Zend_Http_Client::GET);

    }

    public static function parse($response)
    {
        $responseArray = explode("&", $response);

        $result = array();

        if (count($responseArray) > 0) {
            foreach ($responseArray as $i => $value) {

                $keyValuePair = explode("=", $value);

                if (sizeof($keyValuePair) > 1) {
                    $result[$keyValuePair[0]] = urldecode($keyValuePair[1]);
                }
            }
        }
        return $result;
    }

    /**
     *
     * Calls the 'ECDoExpressCheckout' API call. Requires a token that can
     * be obtained using the 'SetExpressCheckout' API call. The payer_id is
     * obtained from the 'SetExpressCheckout' or 'GetExpressCheckoutDetails' API call.
     *
     * @param string $token
     * @param string $payer_id
     * @param float  $payment_amount
     * @param string $currency_code
     * @param string $payment_action Can be 'Authorization', 'Sale', or 'Order'
     *
     * @return \Zend_Http_Response
     * @throws \Zend_Http_Client_Exception
     */
    function ecDoExpressCheckout($token, $payer_id, $payment_amount, $currency_code = 'USD', $payment_action = 'Sale')
    {
        $this->setParameterGet('METHOD', 'DoExpressCheckoutPayment');
        $this->setParameterGet('AMT', $payment_amount);
        $this->setParameterGet('TOKEN', $token);
        $this->setParameterGet('PAYERID', $payer_id);
        $this->setParameterGet('PAYMENTACTION', $payment_action); // Can be 'Authorization', 'Sale', or 'Order'

        return $this->request(\Zend_Http_Client::GET);
    }

    /**
     * Request an authorization token.
     *
     * @param float $paymentAmount
     * @param string $returnURL
     * @param string $cancelURL
     * @param string $currencyID
     * @param string $payment_action Can be 'Authorization', 'Sale', or 'Order'. Default is 'Authorization'
     * @return \Zend_Http_Response
     */
    function ecSetExpressCheckout($returnURL, $cancelURL, $items, $currencyID = 'USD', $payment_action = 'Authorization')
    {
        $this->setParameterGet('METHOD', 'SetExpressCheckout');

        // The paypal PDF says to use this and not AMT, but in practice,
        // that doesnt work yet as of the time of this writting...
        //        $this->setParameterGet('PAYMENTREQUEST_0_AMT', $paymentAmount);

        // ...So we will do this for now.
        $this->_expressStrategy->setParams($this, $items);
        $amt = $this->_expressStrategy->getTotalAmount($items);

        $this->setParameterGet('AMT', $amt);

        $this->setParameterGet('PAYMENTREQUEST_0_CURRENCYCODE', $currencyID);
        $this->setParameterGet('RETURNURL', $returnURL);
        $this->setParameterGet('CANCELURL', $cancelURL);
        $this->setParameterGet('PAYMENTREQUEST_0_PAYMENTACTION', $payment_action); // Can be 'Authorization', 'Sale', or 'Order'

        return $this->request(\Zend_Http_Client::GET);
    }

    /**
     * Returns transaction info.
     * @param $id
     * @return \Zend_Http_Response
     */
    function ecGetTransactionInfo($id)
    {
        $this->setParameterGet('METHOD', 'GetTransactionDetails');
        $this->setParameterGet('TRANSACTIONID', $id);

        return $this->request(\Zend_Http_Client::GET);
    }

    /**
     * @param \G4T\Payment\ExpressStrategy $expressStrategy
     */
    public function setExpressStrategy(ExpressStrategy $expressStrategy)
    {
        $this->_expressStrategy = $expressStrategy;
    }


}
